package com.fullstack.server.http

import cats.*
import cats.effect.{Async, Resource}
import cats.implicits.*
import com.fullstack.server.endpoints.UserEndpoint
import com.fullstack.server.modules.Core
import com.fullstack.server.service.UserService
import org.http4s.HttpRoutes
import org.typelevel.log4cats.Logger
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.http4s.{Http4sServerInterpreter, Http4sServerOptions}
import sttp.tapir.server.metrics.prometheus.PrometheusMetrics
import sttp.tapir.swagger.bundle.SwaggerInterpreter

class RouteApi [F[_]: Async: Logger] private(core: Core[F]) {
  
  val userEndpoint: UserEndpoint[F] = UserEndpoint[F](UserService[F](core.users))
  
  
  // 在这里下面可以 ++ 其它的接口
  val apiEndpoints: List[ServerEndpoint[Any, F]] =
      userEndpoint.all

  
  val docEndpoints: List[ServerEndpoint[Any, F]] = SwaggerInterpreter()
    .fromServerEndpoints[F](apiEndpoints, "full-stack", "1.0.0")

  val prometheusMetrics: PrometheusMetrics[F] = PrometheusMetrics.default[F]()
  val metricsEndpoint: ServerEndpoint[Any, F] = prometheusMetrics.metricsEndpoint

  val all: List[ServerEndpoint[Any, F]] = apiEndpoints ++ docEndpoints ++ List(metricsEndpoint)

  val serverOptions: Http4sServerOptions[F] =
    Http4sServerOptions
      .customiseInterceptors[F]
      .metricsInterceptor(prometheusMetrics.metricsInterceptor())
      .options

  val routes: HttpRoutes[F] = Http4sServerInterpreter[F](serverOptions).toRoutes(all)

}

object RouteApi:

  def apply[F[_] : Async : Logger](core: Core[F]): Resource[F, RouteApi[F]] =

    Resource.eval{
      new RouteApi[F](core).pure[F]
    }

end RouteApi
